home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1999 March
/
EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso
/
earcd
/
devel
/
vbcc-68k-src
/
machines
/
amiga68k
/
libsrc
/
ixemul
/
crt0.asm
next >
Wrap
Assembly Source File
|
1999-01-01
|
10KB
|
436 lines
**
** crt0.asm / ixemul startup code for vbcc/PhxLnk
**
** This startup code will need at least PhxLnk v4.30 to find all
** the required linker symbols.
**
** Based on crt0.c by Loren J. Rittle
** Written by Frank Wille 1997
**
** Assemble with BASECRT0 set, to generate the small data version.
**
** started: 07-Jan-97
**
** v0.1 (08-Jan-97) hard-coded __stk_limit, __stk_argbytes and __machtype,
** no small data support, no moncontrol support for
** profiling, etc... ;)
** v0.2 (09-Jan-97) omitting the __init_stk_limit()-call seems to be a better
** solution for the __stk_limit/__stk_argbytes problem (?)
** v0.9 (10-Jan-97) removed some obsolete xdefs, minor code optimizations,
** small data support by setting BASECRT0 (!)
** v1.0 (02-Feb-97) supports some (all?) nice ixemul.library v45 features
** (e.g. automatic stack extension, some network ini-
** tialization, etc.) so that v45 is *required* from now
** on,
** ___ixemulVer may be defined by the user to set the
** mininum ixemul-version, which the program requires,
** besides ___ixemulVer, some other symbols have moved
** into the ixemul.lib to give the user the possibility
** to overwrite them by an own definition: _expand_cmd_line,
** ___stk_limit, ___stk_argbytes and ___stack,
** the __init_stk_limit()-call is in the startup code again,
** BASECRT0 mode needs the exec-entries a_bss set to zero
** and a_data = _DATA_LEN_ + _BSS_LEN_, this is done by
** importing the new linker symbol _SMALL_DATA_LEN_, which
** PhxLnk defines since v4.30
**
IX_VERSION equ 45 ; minimum version for startup code
; exec.library LVOs
OpenLibrary equ -552
CloseLibrary equ -414
Forbid equ -132
GetMsg equ -372
ReplyMsg equ -378
WaitPort equ -384
CopyMem equ -624
; dos.library LVOs
FilePart equ -870
; intuition.library LVOs
EasyRequestArgs equ -588
; ixemul.library LVOs
ix_startup equ -552
ix_exec_entry equ -1896
ix_get_vars2 equ -1902
ix_resident equ -2568
__init_stk_limit equ -2904
__stkext_startup equ -3450
include "exec/execbase.i"
include "exec/libraries.i"
include "dos/dosextens.i"
include "intuition/intuition.i"
code
xref _main
xref _CODE_LEN_ ; linker symbols, generated by PhxLnk
xref _DATA_LEN_
xref _BSS_LEN_
; xref ___machtype
___machtype equ 0 ; currently hard-coded
IFD BASECRT0
near a4,-2 ; activate small data mode
xref _SMALL_DATA_LEN_ ; total small data size
nref _expand_cmd_line
nref ___stk_limit
nref ___stk_argbytes
nref ___ixemulVer
nref ___stack
ELSE
xref _expand_cmd_line ; expand wildcards?
xref ___stk_limit
xref ___stk_argbytes
xref ___ixemulVer ; ixemul.library version to open
xref ___stack ; desired stack size
ENDIF
; This is the first code executed. Note that a_magic has to be at
; a known offset from the start of the code section in order for
; execve() to know that the program that it is starting uses the
; ixemul library.
bra.w _ENTRY
; this is a struct exec, for now only OMAGIC is supported
dc.w ___machtype ; a_mid
dc.w @407 ; a_magic = OMAGIC
dc.l _CODE_LEN_ ; a_text
IFND BASECRT0
dc.l _DATA_LEN_ ; a_data
dc.l _BSS_LEN_ ; a_bss
ELSE
dc.l _SMALL_DATA_LEN_
dc.l 0
ENDIF
dc.l 0 ; a_syms
dc.l _exec_entry ; a_entry
dc.l 0 ; a_trsize
dc.l 0 ; a_drsize
abort_txt:
dc.b "Abort",0
liberr_txt:
dc.b "Need at least version %ld of ixemul.library.",0
crt_txt:
IFD BASECRT0
dc.b "b"
ENDIF
dc.b "crt0",0
even
xdef _ix_get_variables ; should this be extern?
_ix_get_variables:
; int from_vfork_setup_child (0 or 1)
move.l _ixemulbase,a0
pea __res_socket
lea __res,a1 ; set resolver state default settings
move.l a1,-(sp)
move.l #5,(a1)+ ; retrans = RES_TIMEOUT
move.l #4,(a1)+ ; retry = 4
move.l #$2c0,(a1)+ ; options = RES_DEFAULT
move.l #1,(a1)+ ; nscount = 1
pea _h_errno
tst.l 4*4(sp) ; from_vfork_setup_child ?
beq .1
pea _errno
pea _environ
bra .2
.1: clr.l -(sp)
clr.l -(sp)
.2: pea _environ
pea ___sF
pea _DOSBase
pea _SysBase
pea _sys_nerr
pea __ctype_
pea 11.w
jsr ix_get_vars2(a0)
add.w #48,sp
rts
_start_stdio:
; int argc, char **argv, char **env
move.l a6,-(sp)
clr.l -(sp)
bsr _ix_get_variables ; init SysBase, DOSBase, etc.
; we call a v36 dos.library function here, because crt0 should have
; already failed on a pre-v36 system.
move.l _DOSBase,a6
move.l 4*4(sp),a0
move.l (a0),d1 ; argv[0]
beq .1
jsr FilePart(a6) ; get program name
move.l d0,___progname
; call main
.1: movem.l 3*4(sp),d0-d1/a0 ; argc, argv, env
move.l a0,_environ
movem.l d0-d1/a0,-(sp)
jsr _main ; call main(argc,argv,env) entry point
add.w #16,sp
move.l (sp)+,a6
rts
_exec_entry:
; struct Library *ibase, int argc, char *argv[], char *env[]
IFD BASECRT0
bsr _geta4
move.l 4(sp),a0 ; ibase
move.l a4,-(sp)
pea 2.w
jsr ix_resident(a0)
addq.w #8,sp
ENDIF
move.l 4(sp),a0 ; ibase
move.l a0,_ixemulbase ; set ixemulbase
move.l ___ixemulVer,d0
cmp.w LIB_VERSION(a0),d0
bls .1 ; version ok?
move.l 4.w,a6
move.l d0,-(sp)
pea abort_txt(pc)
pea liberr_txt(pc)
pea crt_txt(pc)
subq.w #8,sp
bsr ix_panic
add.w #24,sp
move.l #(20<<8)|0,d0 ; W_EXITCODE(20,0)
rts
.1 move.l a0,-(sp)
move.l ___stk_argbytes,-(sp)
pea ___stk_limit
jsr __init_stk_limit(a0)
addq.w #8,sp
move.l (sp)+,a0
pea _start_stdio(pc)
pea _errno
move.l 24(sp),-(sp) ; env
move.l 24(sp),-(sp) ; argv
move.l 24(sp),-(sp) ; argc
move.l ___stack,d0 ; desired stack size set?
beq .2
jsr __stkext_startup(a0) ; stack extension, if required
.2 jsr ix_exec_entry(a0)
add.w #20,sp
rts
IFD BASECRT0
xref _DATA_BAS_
xdef _geta4
_geta4:
lea _DATA_BAS_+32766,a4 ; init small data base register
rts
ENDIF
; Note: This routine must be far enough away from the start of code
; so that the PC relative offset won't fit in a byte and the assembler
; will generate the right instruction pattern that execve() is looking
; for to know that this is a program that uses the ixemul.library.
_ENTRY:
IFD BASECRT0
movem.l d2/a2/a4/a6,-(sp)
bsr _geta4
ELSE
movem.l d2/a2/a6,-(sp)
ENDIF
move.l a0,d2 ; a2/d2 save command line
move.l d0,a2
move.l 4.w,a6 ; ExecBase (v37)
cmp.w #37,LIB_VERSION(a6) ; required for StackSwap()
blo .6
move.l ___ixemulVer,d0 ; user-defined version
moveq #IX_VERSION,d1 ; minimum version required
cmp.l d1,d0
bhs .4
move.l d1,d0
move.l d0,___ixemulVer
.4: lea ixemul_name(pc),a1
jsr OpenLibrary(a6) ; open ixemul.library
move.l d0,_ixemulbase
beq .1
move.l d0,a6 ; a6 ixemulbase
IFD BASECRT0
move.l a4,-(sp)
pea 2.w
jsr ix_resident(a6)
addq.w #8,sp
ENDIF
move.l ___stk_argbytes,-(sp)
pea ___stk_limit
jsr __init_stk_limit(a6)
pea _errno
pea _start_stdio(pc)
move.l _default_wb_window,-(sp)
move.l _expand_cmd_line,-(sp)
move.l a2,-(sp)
move.l d2,-(sp)
move.l ___stack,d0 ; desired stack size set?
beq .5
jsr __stkext_startup(a6) ; stack extension, if required
.5: jsr ix_startup(a6) ; ixemul startup
move.l d0,d2
add.w #32,sp
move.l a6,a1
move.l 4.w,a6
jsr CloseLibrary(a6) ; close ixemul.library
move.l d2,d0
bra .3
.1: move.l ___ixemulVer,-(sp) ; error on opening ixemul.library
pea abort_txt(pc)
pea liberr_txt(pc)
pea crt_txt(pc)
subq.w #8,sp
bsr ix_panic
add.w #24,sp
.6: move.l ThisTask(a6),a2
tst.l pr_CLI(a2) ; started from CLI?
bne .2
; Quickly deal with the WB startup message, as the library couldn't do
; this for us. Nothing at all is done that isn't necessary to just shutup
; workbench.
jsr Forbid(a6)
add.w #pr_MsgPort,a2
move.l a2,a0
jsr WaitPort(a6)
move.l a2,a0
jsr GetMsg(a6)
move.l d0,a1
jsr ReplyMsg(a6) ; reply WBStartup message
.2: moveq #20,d0
.3:
IFD BASECRT0
movem.l (sp)+,d2/a2/a4/a6
ELSE
movem.l (sp)+,d2/a2/a6
ENDIF
rts
ixemul_name:
dc.b "ixemul.library",0
intuition_name:
dc.b "intuition.library",0
even
ix_panic:
; Displays a v36 easy-requester.
; A comlete EasyStruct is already on stack, when called. Only es_StructSize
; and es_Flags will be initialized here.
; a6 = ExecBase
lea intuition_name(pc),a1
moveq #36,d0
jsr OpenLibrary(a6) ; open intuition.library v36
tst.l d0
beq .1
movem.l a2-a3/a6,-(sp)
move.l d0,a6 ; IntuitionBase
sub.l a0,a0
lea 4*4(sp),a1 ; EasyStruct
move.l #EasyStruct_SIZEOF,es_StructSize(a1)
clr.l es_Flags(a1)
sub.l a2,a2
lea EasyStruct_SIZEOF(a1),a3 ; ArgList
jsr EasyRequestArgs(a6) ; render panic requester
move.l a6,a1
movem.l (sp)+,a2-a3/a6
jsr CloseLibrary(a6) ; close intuition.library
.1: rts
; null mcount and moncontrol, just in case some routine is
; compiled for profiling
xdef mcount
xdef _moncontrol
_moncontrol:
mcount:
rts
IFD BASECRT0
section __MERGED,data
ELSE
data
ENDIF
_environ:
dc.l dummy_environ ; default for progs not started via exec_entry
___progname:
dc.l dummy_environ ; use dummy_environ as empty string
__res_socket: ; resolv socket used for communications
dc.l -1
xdef _environ
xdef ___progname
xdef __res_socket
IFD BASECRT0
section __MERGED,bss
ELSE
bss
ENDIF
_ixemulbase:
ds.l 1
_errno: ; error results from the library
ds.l 1
__ctype_:
ds.l 1
_sys_nerr: ; number of system error codes
ds.l 1
_SysBase:
ds.l 1
_DOSBase:
ds.l 1
___sF:
ds.l 1
___SaveSP:
ds.l 1
dummy_environ:
ds.l 1
_default_wb_window: ; Default Workbench output window name
ds.l 1
_h_errno:
ds.l 1 ; networking error code
__res: ; resolver state
ds.b 448 ; sizeof(struct __rest_state) + some extra bytes
xdef _ixemulbase
xdef _errno
xdef __ctype_
xdef _sys_nerr
xdef _SysBase
xdef _DOSBase
xdef ___sF
xdef ___SaveSP
xdef _h_errno
xdef __res
end